from configs.constants import constants
from models.code_record import CodeGenerationRecord
from repositories.code_record_repo import CodeGenerationRecordRepository

class CodeRecordGenerationService:

    def __init__(self):
        self.repository = CodeGenerationRecordRepository()

    def create_record(self, record_data, intermediate_model_responses) -> int:
        record = CodeGenerationRecord()
        record.module_id = record_data["moduleId"]
        record.module_name = record_data["moduleName"]
        record.data_dictionary = record_data["dict"]
        record.original_pseudo_code = record_data["pseudoCode"]
        record.plugin_version = record_data["pluginVersion"]
        record.invocation_method = (
            constants.InvocationMethodType.PUBLIC
            if record_data["invocationMethod"] == 'public'
            else constants.InvocationMethodType.PRIVATE
        )
        record.normalized_intermediate_1 = intermediate_model_responses[0]
        record.normalized_intermediate_2 = intermediate_model_responses[1]
        record.normalized_intermediate_3 = intermediate_model_responses[2]
        record.normalized_intermediate_4 = intermediate_model_responses[3]
        record.normalized_intermediate_5 = intermediate_model_responses[4]
        record.normalized_intermediate_6 = intermediate_model_responses[5]

        return self.repository.insert(record)

    def create_or_update_record_pseudo_code(self, record_data, intermediate_model_responses):
        module_id = record_data["moduleId"]
        record = self.repository.get_latest_by_module_id(module_id)
        if record is None or record.c_code_status != constants.CCodeStatus.NOT_GENERATED:
            self.create_record(record_data, intermediate_model_responses)
        else:
            record.module_name = record_data["moduleName"]
            record.data_dictionary = record_data["dict"]
            record.original_pseudo_code = record_data["pseudoCode"]
            record.plugin_version = record_data["pluginVersion"]
            record.invocation_method = (
                constants.InvocationMethodType.PUBLIC
                if record_data["invocationMethod"] == 'public'
                else constants.InvocationMethodType.PRIVATE
            )
            record.normalized_intermediate_1 = intermediate_model_responses[0]
            record.normalized_intermediate_2 = intermediate_model_responses[1]
            record.normalized_intermediate_3 = intermediate_model_responses[2]
            record.normalized_intermediate_4 = intermediate_model_responses[3]
            record.normalized_intermediate_5 = intermediate_model_responses[4]
            record.normalized_intermediate_6 = intermediate_model_responses[5]
            self.repository.update(record)

    def update_record_c_status(self, module_id, module_name, normalized_pseudo_code, c_code, c_code_error):
        record = self.repository.get_latest_by_module_id(module_id)

        if record is None:
            record = CodeGenerationRecord()
            record.module_id = module_id
            record.module_name = module_name
            record.normalized_pseudo_code = normalized_pseudo_code
            record.generated_c_code = c_code
            record.c_code_errr = c_code_error
            record.c_code_status = (
                constants.CCodeStatus.GENERATED_SUCCESSFULLY
                if c_code_error is None
                else constants.CCodeStatus.GENERATED_FAILED
            )
            self.repository.insert(record)
            return

        flag = record.c_code_status == constants.CCodeStatus.NOT_GENERATED

        needs_update = (
            flag or
            record.normalized_pseudo_code != normalized_pseudo_code or
            record.generated_c_code != c_code or
            record.c_code_error != c_code_error
        )

        if not needs_update:
            return

        record.normalized_pseudo_code = normalized_pseudo_code
        record.generated_c_code = c_code
        record.c_code_error = c_code_error
        record.c_code_status = (
            constants.CCodeStatus.GENERATED_SUCCESSFULLY
            if c_code_error is None
            else constants.CCodeStatus.GENERATED_FAILED
        )

        if flag:
            self.repository.update(record)
        else:
            self.repository.insert(record)

if __name__ == "__main__":
    service = CodeRecordGenerationService()
    record_data = {
        "moduleId": "als-00d9ajzxhehnsa-1ndujx",
        "moduleName": "module-name-00123",
        "dict": "{",
        "pseudoCode": "if a == 1 a = b",
        "pluginVersion": "plugin_version-00123",
        "invocationMethod": "public",
    }
    service.create_record(record_data, intermediate_model_responses=["code1", "code2", "code3", "code4", "code5", "code6"])